﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using TestXNA3.Actors;
using TestXNA3.Components;
using Microsoft.Xna.Framework.Input;
using TestXNA3.Resources;
using TestXNA3.Resources.Shaders;
using Microsoft.Xna.Framework.Graphics;
using ModelImporter;
using System.IO;
using TestXNA3.Render;

namespace TestXNA3.Games.TestGame
{
    class TestGameInfo : GameInfo
    {
        class FireBlast : PointLight
        {
            float lifetime;
            protected override void postUpdate(float dt)
            {
                lifetime += dt;
                //Location += Forward * 2.0f;
                base.postUpdate(dt);

                Intensity = (lifetime > 4.0f)? (8.0f - lifetime) / 4.0f : 1.0f;
                Radius *= Intensity;

                if (lifetime > 8.0f)
                {
                    Parent.DetachActor(this);
                }
            }
        }

        public TestGameInfo()
        {
        }

        public override void Initialize()
        {
            base.Initialize();

            MainCamera.Location = new Vector3(0, 16.0f, 32.0f);
            //MainCamera.RotateX(-90.0f);

            Scene.PhysicsScene.Gravity = new Vector3(0, -9.81f, 0);
            /*
            StaticMeshComponent sm = null;

            // Test plane
            {
                Actor testActor = new Actor();
                sm = new StaticMeshComponent("plane_");
                ((StaticMeshDefaultShader)sm.StaticMesh.Shader).Diffuse = new TextureResource("wall");
                ((StaticMeshDefaultShader)sm.StaticMesh.Shader).Normal = new TextureResource("wall_NM_height");
                testActor.AttachComponent(sm);
                Scene.AttachActor(testActor);

                PhysicsComponent testPlanePhysComp = new PhysicsComponent();
                testActor.AttachComponent(testPlanePhysComp);

                StillDesign.PhysX.TriangleMeshShapeDescription triShapeDesc = new StillDesign.PhysX.TriangleMeshShapeDescription();
                triShapeDesc.TriangleMesh = sm.StaticMesh.TriMesh;

                StillDesign.PhysX.ActorDescription actorDesc = new StillDesign.PhysX.ActorDescription();
                actorDesc.GlobalPose = testActor.Axis;
                actorDesc.Shapes.Add(triShapeDesc);

                testPlanePhysComp.Body = Scene.PhysicsScene.CreateActor(actorDesc);
            }

            // Test ball
            {
                Actor testBall = new Actor();
                Scene.AttachActor(testBall);
                sm = new StaticMeshComponent("sphere_");
                ((StaticMeshDefaultShader)sm.StaticMesh.Shader).Diffuse = new TextureResource("default");
                ((StaticMeshDefaultShader)sm.StaticMesh.Shader).Normal = new TextureResource("default_normal");
                testBall.Location = new Vector3(0, 256, 0);
                testBall.AttachComponent(sm);

                PhysicsComponent testBallPhysComp = new PhysicsComponent();
                testBall.AttachComponent(testBallPhysComp);

                //StillDesign.PhysX.BoxShapeDescription boxShapeDesc = new StillDesign.PhysX.BoxShapeDescription(sm.StaticMesh.Desc.BoundsMax - sm.StaticMesh.Desc.BoundsMin);
                //StillDesign.PhysX.TriangleMeshShapeDescription boxShapeDesc = new StillDesign.PhysX.TriangleMeshShapeDescription();
                //boxShapeDesc.TriangleMesh = GameStartup.PhysXCore.CreateTriangleMesh(sm.StaticMesh.Desc.TriMesh);
                //StillDesign.PhysX.ConvexShapeDescription boxShapeDesc = new StillDesign.PhysX.ConvexShapeDescription(GameStartup.PhysXCore.CreateConvexMesh(sm.StaticMesh.Desc.ConvexMesh));
                StillDesign.PhysX.SphereShapeDescription boxShapeDesc = new StillDesign.PhysX.SphereShapeDescription(14.0f);

                StillDesign.PhysX.ActorDescription actorDesc = new StillDesign.PhysX.ActorDescription();
                actorDesc.BodyDescription = new StillDesign.PhysX.BodyDescription(15.0f);
                actorDesc.GlobalPose = testBall.Axis;
                actorDesc.Shapes.Add(boxShapeDesc);
                testBallPhysComp.Body = Scene.PhysicsScene.CreateActor(actorDesc);

                testBall.Scale = new Vector3(0.1f, 0.1f, 0.1f);
            }

            // Test lights
            PointLight light = new PointLight();
            light.Location = new Vector3(0, 12.0f, 0);
            light.Diffuse = Color.AliceBlue;
            light.Radius = 384.0f;
            Scene.AttachActor(light);

            DirectionalLight sun = new DirectionalLight();
            sun.Yaw = -30.0f;
            sun.Pitch = -60.0f;
            sun.Diffuse = Color.AntiqueWhite;
            sun.Intensity = 1.0f;
            Scene.AttachActor(sun);*/

            string mapName = TestConfig.ParseOption("map");
            if (mapName.Length > 1)
            {
                Map.Load(mapName);
            }
        }

        private float lastTimeFired = 0.0f;

        public override void Update(float dt)
        {
            KeyboardState currentKeyboardState = Keyboard.GetState();
            MouseState currentMouseState = Mouse.GetState();

            float speedScale = 128.0f;


            if (currentKeyboardState.IsKeyDown(Keys.LeftShift))
            {
                speedScale *= 20.0f;
            }

            if (currentKeyboardState.IsKeyDown(Keys.W))
            {
                MainCamera.Location = MainCamera.Location + MainCamera.Forward * speedScale * dt;
            }
            if (currentKeyboardState.IsKeyDown(Keys.S))
            {
                MainCamera.Location = MainCamera.Location - MainCamera.Forward * speedScale * dt;
            }

            if (currentKeyboardState.IsKeyDown(Keys.A))
            {
                MainCamera.Location = MainCamera.Location - MainCamera.Right * speedScale * dt;
            }
            if (currentKeyboardState.IsKeyDown(Keys.D))
            {
                MainCamera.Location = MainCamera.Location + MainCamera.Right * speedScale * dt;
            }
            
            if (currentKeyboardState.IsKeyDown(Keys.Space))
            {
                if ((GameStartup.StaticGameStartup.GameInfo.TimeSeconds - lastTimeFired) > 1.0f)
                {
                    lastTimeFired = (float)GameStartup.StaticGameStartup.GameInfo.TimeSeconds;
                    Actor sm = new Actor();
                    sm.Location = MainCamera.Location;
                    //sm.Scale = new Vector3(0.3f, 0.3f, 0.3f);
                    SkeletalMeshComponent smc = new SkeletalMeshComponent("trooper/trooper", "trooper");
                    sm.AttachComponent(smc);
                    Scene.AttachActor(sm);
                }
            }

            if (currentMouseState.RightButton == ButtonState.Pressed)// && currentMouseState.LeftButton == ButtonState.Pressed)
            {
                float x = currentMouseState.X;
                float y = currentMouseState.Y;
                int centerX = GameStartup.Graphics.PresentationParameters.BackBufferWidth / 2;
                int centerY = GameStartup.Graphics.PresentationParameters.BackBufferHeight / 2;
                x -= centerX;
                y -= centerY;
                MainCamera.Yaw += -(((float)(currentMouseState.X - centerX)) * 0.1f);
                MainCamera.Pitch += -(((float)(currentMouseState.Y - centerY)) * 0.1f);


                Mouse.SetPosition(centerX, centerY);
            }
            else
            {
                GameStartup.StaticGameStartup.IsMouseVisible = true;
            }

            base.Update(dt);
        }
    }
}
